/**
 * @file RequestUtils.h
 * @brief Utility class for handling file content in HTTP requests
 * @author CloudLinker
 * @date 2023-11-20
 */

#pragma once

#include <string>
#include <vector>
#include <map>
#include <optional>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/PartHandler.h>

#include "../CLink_Export.h"

namespace CLink
{
namespace Utils
{

/**
 * @class RequestUtils
 * @brief 请求工具类，提供处理HTTP请求中文件内容的功能
 */
class CLINK_CLASS RequestUtils
{
public:
    /**
     * @brief 文件内容结构体
     */
    struct FileContent
    {
        std::string name;            ///< 文件名
        std::string contentType;     ///< 文件类型
        std::vector<char> data;      ///< 文件数据
    };

    /**
     * @brief 处理多部分表单数据中的文件
     * @param request HTTP请求对象
     * @param boundary 多部分边界字符串
     * @return 包含所有文件内容的向量，如果没有文件则返回空向量
     */
    static std::vector<FileContent> handleMultipartFiles(
        const Poco::Net::HTTPRequest& request,
        const std::string& boundary);

    /**
     * @brief 从请求中提取单个文件
     * @param request HTTP请求对象
     * @param paramName 参数名
     * @return 文件内容，如果不存在则返回空对象
     */
    static std::optional<FileContent> extractFile(
        const Poco::Net::HTTPRequest& request,
        const std::string& paramName);

    /**
     * @brief 从请求中提取所有文件
     * @param request HTTP请求对象
     * @return 文件名到文件内容的映射
     */
    static std::map<std::string, FileContent> extractAllFiles(
        const Poco::Net::HTTPRequest& request);

    /**
     * @brief 检查请求是否包含文件
     * @param request HTTP请求对象
     * @return 如果请求包含文件则返回true，否则返回false
     */
    static bool hasFiles(const Poco::Net::HTTPRequest& request);

private:
    /**
     * @brief 自定义PartHandler用于处理多部分数据
     */
    class FilePartHandler : public Poco::Net::PartHandler
    {
    public:
        /**
         * @brief 处理部分数据
         * @param header 部分头信息
         * @param stream 输入流
         */
        void handlePart(const Poco::Net::MessageHeader& header, 
                       std::istream& stream) override;

        /// 获取处理后的文件内容
        std::vector<FileContent> getFiles() const { return files_; }

    private:
        std::vector<FileContent> files_; ///< 存储处理后的文件内容
    };
};

} // namespace Utils
} // namespace CLink